home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / src / linux-headers-2.6.28-15 / include / linux / regset.h < prev    next >
Encoding:
C/C++ Source or Header  |  2008-12-24  |  12.9 KB  |  369 lines

  1. /*
  2.  * User-mode machine state access
  3.  *
  4.  * Copyright (C) 2007 Red Hat, Inc.  All rights reserved.
  5.  *
  6.  * This copyrighted material is made available to anyone wishing to use,
  7.  * modify, copy, or redistribute it subject to the terms and conditions
  8.  * of the GNU General Public License v.2.
  9.  *
  10.  * Red Hat Author: Roland McGrath.
  11.  */
  12.  
  13. #ifndef _LINUX_REGSET_H
  14. #define _LINUX_REGSET_H    1
  15.  
  16. #include <linux/compiler.h>
  17. #include <linux/types.h>
  18. #include <linux/uaccess.h>
  19. struct task_struct;
  20. struct user_regset;
  21.  
  22.  
  23. /**
  24.  * user_regset_active_fn - type of @active function in &struct user_regset
  25.  * @target:    thread being examined
  26.  * @regset:    regset being examined
  27.  *
  28.  * Return -%ENODEV if not available on the hardware found.
  29.  * Return %0 if no interesting state in this thread.
  30.  * Return >%0 number of @size units of interesting state.
  31.  * Any get call fetching state beyond that number will
  32.  * see the default initialization state for this data,
  33.  * so a caller that knows what the default state is need
  34.  * not copy it all out.
  35.  * This call is optional; the pointer is %NULL if there
  36.  * is no inexpensive check to yield a value < @n.
  37.  */
  38. typedef int user_regset_active_fn(struct task_struct *target,
  39.                   const struct user_regset *regset);
  40.  
  41. /**
  42.  * user_regset_get_fn - type of @get function in &struct user_regset
  43.  * @target:    thread being examined
  44.  * @regset:    regset being examined
  45.  * @pos:    offset into the regset data to access, in bytes
  46.  * @count:    amount of data to copy, in bytes
  47.  * @kbuf:    if not %NULL, a kernel-space pointer to copy into
  48.  * @ubuf:    if @kbuf is %NULL, a user-space pointer to copy into
  49.  *
  50.  * Fetch register values.  Return %0 on success; -%EIO or -%ENODEV
  51.  * are usual failure returns.  The @pos and @count values are in
  52.  * bytes, but must be properly aligned.  If @kbuf is non-null, that
  53.  * buffer is used and @ubuf is ignored.  If @kbuf is %NULL, then
  54.  * ubuf gives a userland pointer to access directly, and an -%EFAULT
  55.  * return value is possible.
  56.  */
  57. typedef int user_regset_get_fn(struct task_struct *target,
  58.                    const struct user_regset *regset,
  59.                    unsigned int pos, unsigned int count,
  60.                    void *kbuf, void __user *ubuf);
  61.  
  62. /**
  63.  * user_regset_set_fn - type of @set function in &struct user_regset
  64.  * @target:    thread being examined
  65.  * @regset:    regset being examined
  66.  * @pos:    offset into the regset data to access, in bytes
  67.  * @count:    amount of data to copy, in bytes
  68.  * @kbuf:    if not %NULL, a kernel-space pointer to copy from
  69.  * @ubuf:    if @kbuf is %NULL, a user-space pointer to copy from
  70.  *
  71.  * Store register values.  Return %0 on success; -%EIO or -%ENODEV
  72.  * are usual failure returns.  The @pos and @count values are in
  73.  * bytes, but must be properly aligned.  If @kbuf is non-null, that
  74.  * buffer is used and @ubuf is ignored.  If @kbuf is %NULL, then
  75.  * ubuf gives a userland pointer to access directly, and an -%EFAULT
  76.  * return value is possible.
  77.  */
  78. typedef int user_regset_set_fn(struct task_struct *target,
  79.                    const struct user_regset *regset,
  80.                    unsigned int pos, unsigned int count,
  81.                    const void *kbuf, const void __user *ubuf);
  82.  
  83. /**
  84.  * user_regset_writeback_fn - type of @writeback function in &struct user_regset
  85.  * @target:    thread being examined
  86.  * @regset:    regset being examined
  87.  * @immediate:    zero if writeback at completion of next context switch is OK
  88.  *
  89.  * This call is optional; usually the pointer is %NULL.  When
  90.  * provided, there is some user memory associated with this regset's
  91.  * hardware, such as memory backing cached register data on register
  92.  * window machines; the regset's data controls what user memory is
  93.  * used (e.g. via the stack pointer value).
  94.  *
  95.  * Write register data back to user memory.  If the @immediate flag
  96.  * is nonzero, it must be written to the user memory so uaccess or
  97.  * access_process_vm() can see it when this call returns; if zero,
  98.  * then it must be written back by the time the task completes a
  99.  * context switch (as synchronized with wait_task_inactive()).
  100.  * Return %0 on success or if there was nothing to do, -%EFAULT for
  101.  * a memory problem (bad stack pointer or whatever), or -%EIO for a
  102.  * hardware problem.
  103.  */
  104. typedef int user_regset_writeback_fn(struct task_struct *target,
  105.                      const struct user_regset *regset,
  106.                      int immediate);
  107.  
  108. /**
  109.  * struct user_regset - accessible thread CPU state
  110.  * @n:            Number of slots (registers).
  111.  * @size:        Size in bytes of a slot (register).
  112.  * @align:        Required alignment, in bytes.
  113.  * @bias:        Bias from natural indexing.
  114.  * @core_note_type:    ELF note @n_type value used in core dumps.
  115.  * @get:        Function to fetch values.
  116.  * @set:        Function to store values.
  117.  * @active:        Function to report if regset is active, or %NULL.
  118.  * @writeback:        Function to write data back to user memory, or %NULL.
  119.  *
  120.  * This data structure describes a machine resource we call a register set.
  121.  * This is part of the state of an individual thread, not necessarily
  122.  * actual CPU registers per se.  A register set consists of a number of
  123.  * similar slots, given by @n.  Each slot is @size bytes, and aligned to
  124.  * @align bytes (which is at least @size).
  125.  *
  126.  * These functions must be called only on the current thread or on a
  127.  * thread that is in %TASK_STOPPED or %TASK_TRACED state, that we are
  128.  * guaranteed will not be woken up and return to user mode, and that we
  129.  * have called wait_task_inactive() on.  (The target thread always might
  130.  * wake up for SIGKILL while these functions are working, in which case
  131.  * that thread's user_regset state might be scrambled.)
  132.  *
  133.  * The @pos argument must be aligned according to @align; the @count
  134.  * argument must be a multiple of @size.  These functions are not
  135.  * responsible for checking for invalid arguments.
  136.  *
  137.  * When there is a natural value to use as an index, @bias gives the
  138.  * difference between the natural index and the slot index for the
  139.  * register set.  For example, x86 GDT segment descriptors form a regset;
  140.  * the segment selector produces a natural index, but only a subset of
  141.  * that index space is available as a regset (the TLS slots); subtracting
  142.  * @bias from a segment selector index value computes the regset slot.
  143.  *
  144.  * If nonzero, @core_note_type gives the n_type field (NT_* value)
  145.  * of the core file note in which this regset's data appears.
  146.  * NT_PRSTATUS is a special case in that the regset data starts at
  147.  * offsetof(struct elf_prstatus, pr_reg) into the note data; that is
  148.  * part of the per-machine ELF formats userland knows about.  In
  149.  * other cases, the core file note contains exactly the whole regset
  150.  * (@n * @size) and nothing else.  The core file note is normally
  151.  * omitted when there is an @active function and it returns zero.
  152.  */
  153. struct user_regset {
  154.     user_regset_get_fn        *get;
  155.     user_regset_set_fn        *set;
  156.     user_regset_active_fn        *active;
  157.     user_regset_writeback_fn    *writeback;
  158.     unsigned int            n;
  159.     unsigned int             size;
  160.     unsigned int             align;
  161.     unsigned int             bias;
  162.     unsigned int             core_note_type;
  163. };
  164.  
  165. /**
  166.  * struct user_regset_view - available regsets
  167.  * @name:    Identifier, e.g. UTS_MACHINE string.
  168.  * @regsets:    Array of @n regsets available in this view.
  169.  * @n:        Number of elements in @regsets.
  170.  * @e_machine:    ELF header @e_machine %EM_* value written in core dumps.
  171.  * @e_flags:    ELF header @e_flags value written in core dumps.
  172.  * @ei_osabi:    ELF header @e_ident[%EI_OSABI] value written in core dumps.
  173.  *
  174.  * A regset view is a collection of regsets (&struct user_regset,
  175.  * above).  This describes all the state of a thread that can be seen
  176.  * from a given architecture/ABI environment.  More than one view might
  177.  * refer to the same &struct user_regset, or more than one regset
  178.  * might refer to the same machine-specific state in the thread.  For
  179.  * example, a 32-bit thread's state could be examined from the 32-bit
  180.  * view or from the 64-bit view.  Either method reaches the same thread
  181.  * register state, doing appropriate widening or truncation.
  182.  */
  183. struct user_regset_view {
  184.     const char *name;
  185.     const struct user_regset *regsets;
  186.     unsigned int n;
  187.     u32 e_flags;
  188.     u16 e_machine;
  189.     u8 ei_osabi;
  190. };
  191.  
  192. /*
  193.  * This is documented here rather than at the definition sites because its
  194.  * implementation is machine-dependent but its interface is universal.
  195.  */
  196. /**
  197.  * task_user_regset_view - Return the process's native regset view.
  198.  * @tsk: a thread of the process in question
  199.  *
  200.  * Return the &struct user_regset_view that is native for the given process.
  201.  * For example, what it would access when it called ptrace().
  202.  * Throughout the life of the process, this only changes at exec.
  203.  */
  204. const struct user_regset_view *task_user_regset_view(struct task_struct *tsk);
  205.  
  206.  
  207. /*
  208.  * These are helpers for writing regset get/set functions in arch code.
  209.  * Because @start_pos and @end_pos are always compile-time constants,
  210.  * these are inlined into very little code though they look large.
  211.  *
  212.  * Use one or more calls sequentially for each chunk of regset data stored
  213.  * contiguously in memory.  Call with constants for @start_pos and @end_pos,
  214.  * giving the range of byte positions in the regset that data corresponds
  215.  * to; @end_pos can be -1 if this chunk is at the end of the regset layout.
  216.  * Each call updates the arguments to point past its chunk.
  217.  */
  218.  
  219. static inline int user_regset_copyout(unsigned int *pos, unsigned int *count,
  220.                       void **kbuf,
  221.                       void __user **ubuf, const void *data,
  222.                       const int start_pos, const int end_pos)
  223. {
  224.     if (*count == 0)
  225.         return 0;
  226.     BUG_ON(*pos < start_pos);
  227.     if (end_pos < 0 || *pos < end_pos) {
  228.         unsigned int copy = (end_pos < 0 ? *count
  229.                      : min(*count, end_pos - *pos));
  230.         data += *pos - start_pos;
  231.         if (*kbuf) {
  232.             memcpy(*kbuf, data, copy);
  233.             *kbuf += copy;
  234.         } else if (__copy_to_user(*ubuf, data, copy))
  235.             return -EFAULT;
  236.         else
  237.             *ubuf += copy;
  238.         *pos += copy;
  239.         *count -= copy;
  240.     }
  241.     return 0;
  242. }
  243.  
  244. static inline int user_regset_copyin(unsigned int *pos, unsigned int *count,
  245.                      const void **kbuf,
  246.                      const void __user **ubuf, void *data,
  247.                      const int start_pos, const int end_pos)
  248. {
  249.     if (*count == 0)
  250.         return 0;
  251.     BUG_ON(*pos < start_pos);
  252.     if (end_pos < 0 || *pos < end_pos) {
  253.         unsigned int copy = (end_pos < 0 ? *count
  254.                      : min(*count, end_pos - *pos));
  255.         data += *pos - start_pos;
  256.         if (*kbuf) {
  257.             memcpy(data, *kbuf, copy);
  258.             *kbuf += copy;
  259.         } else if (__copy_from_user(data, *ubuf, copy))
  260.             return -EFAULT;
  261.         else
  262.             *ubuf += copy;
  263.         *pos += copy;
  264.         *count -= copy;
  265.     }
  266.     return 0;
  267. }
  268.  
  269. /*
  270.  * These two parallel the two above, but for portions of a regset layout
  271.  * that always read as all-zero or for which writes are ignored.
  272.  */
  273. static inline int user_regset_copyout_zero(unsigned int *pos,
  274.                        unsigned int *count,
  275.                        void **kbuf, void __user **ubuf,
  276.                        const int start_pos,
  277.                        const int end_pos)
  278. {
  279.     if (*count == 0)
  280.         return 0;
  281.     BUG_ON(*pos < start_pos);
  282.     if (end_pos < 0 || *pos < end_pos) {
  283.         unsigned int copy = (end_pos < 0 ? *count
  284.                      : min(*count, end_pos - *pos));
  285.         if (*kbuf) {
  286.             memset(*kbuf, 0, copy);
  287.             *kbuf += copy;
  288.         } else if (__clear_user(*ubuf, copy))
  289.             return -EFAULT;
  290.         else
  291.             *ubuf += copy;
  292.         *pos += copy;
  293.         *count -= copy;
  294.     }
  295.     return 0;
  296. }
  297.  
  298. static inline int user_regset_copyin_ignore(unsigned int *pos,
  299.                         unsigned int *count,
  300.                         const void **kbuf,
  301.                         const void __user **ubuf,
  302.                         const int start_pos,
  303.                         const int end_pos)
  304. {
  305.     if (*count == 0)
  306.         return 0;
  307.     BUG_ON(*pos < start_pos);
  308.     if (end_pos < 0 || *pos < end_pos) {
  309.         unsigned int copy = (end_pos < 0 ? *count
  310.                      : min(*count, end_pos - *pos));
  311.         if (*kbuf)
  312.             *kbuf += copy;
  313.         else
  314.             *ubuf += copy;
  315.         *pos += copy;
  316.         *count -= copy;
  317.     }
  318.     return 0;
  319. }
  320.  
  321. /**
  322.  * copy_regset_to_user - fetch a thread's user_regset data into user memory
  323.  * @target:    thread to be examined
  324.  * @view:    &struct user_regset_view describing user thread machine state
  325.  * @setno:    index in @view->regsets
  326.  * @offset:    offset into the regset data, in bytes
  327.  * @size:    amount of data to copy, in bytes
  328.  * @data:    user-mode pointer to copy into
  329.  */
  330. static inline int copy_regset_to_user(struct task_struct *target,
  331.                       const struct user_regset_view *view,
  332.                       unsigned int setno,
  333.                       unsigned int offset, unsigned int size,
  334.                       void __user *data)
  335. {
  336.     const struct user_regset *regset = &view->regsets[setno];
  337.  
  338.     if (!access_ok(VERIFY_WRITE, data, size))
  339.         return -EIO;
  340.  
  341.     return regset->get(target, regset, offset, size, NULL, data);
  342. }
  343.  
  344. /**
  345.  * copy_regset_from_user - store into thread's user_regset data from user memory
  346.  * @target:    thread to be examined
  347.  * @view:    &struct user_regset_view describing user thread machine state
  348.  * @setno:    index in @view->regsets
  349.  * @offset:    offset into the regset data, in bytes
  350.  * @size:    amount of data to copy, in bytes
  351.  * @data:    user-mode pointer to copy from
  352.  */
  353. static inline int copy_regset_from_user(struct task_struct *target,
  354.                     const struct user_regset_view *view,
  355.                     unsigned int setno,
  356.                     unsigned int offset, unsigned int size,
  357.                     const void __user *data)
  358. {
  359.     const struct user_regset *regset = &view->regsets[setno];
  360.  
  361.     if (!access_ok(VERIFY_READ, data, size))
  362.         return -EIO;
  363.  
  364.     return regset->set(target, regset, offset, size, NULL, data);
  365. }
  366.  
  367.  
  368. #endif    /* <linux/regset.h> */
  369.